Load libraries
library(tidytext)
library(tidyverse)
library(quanteda)
library(lubridate)
library(ggplot2)
library(plotly)
library(forcats)
library(readxl)
library(leaflet)
library(leaflet.minicharts)
library(sp)
library(sf)
library(readr)
library(stringr)
library(rtweet)
Load Data
Parlamentarier <- read_csv("Data/Parlamentarier.csv")
EU-Parlament rausfiltern
Parlamentarier <- Parlamentarier %>%
filter(Kategorie!="EU-Parlament")
Read Tabellen mit fehlenden Geschlechtern
alle_geschlechter <- read_excel("Data/Parlamentarier_geschechter.xlsx", sheet = "Geschlechter")
Join fehlende Geschlechterangaben
Parlamentarier <- Parlamentarier %>%
left_join(alle_geschlechter, by = c("Name" = "Name"))
Rename Spalten
Parlamentarier <- Parlamentarier %>%
rename(Geschlecht = Geschlecht.y)
Bundestag Geschlechterverteilung Partei
bundestag <- Parlamentarier %>%
select(id, Name, Geschlecht, Partei, Kategorie, SM_Twitter_id, SM_Twitter_user) %>%
filter(Kategorie=="Bundestag")
bundestag$Partei[bundestag$Partei == "CSU"] <-"CDU/CSU"
bundestag$Partei[bundestag$Partei=="CDU"]<-"CDU/CSU"
bundestag_man <- bundestag %>%
group_by(Partei) %>%
filter(Geschlecht == "männlich") %>%
summarise(gesamt_man=n())
bundestag_gesamt <- bundestag %>%
group_by(Partei) %>%
filter(Geschlecht == "weiblich") %>%
summarise(gesamt_frau=n()) %>%
left_join(bundestag_man) %>%
mutate(row_sum=rowSums(.[2:3])) %>%
arrange(desc(row_sum))
Barchart Bundestag
plot_ly(data=bundestag_gesamt, x=~reorder(Partei,-row_sum), y=~gesamt_frau, name="weiblich", marker=list(color=toRGB("#FB7F62")),
type="bar", hoverinfo="text", text=~paste("",row_sum),
hovertemplate=paste("Anzahl: %{y:,.0f}",
"<br>Gesamtanzahl: %{text}")) %>%
add_trace(y=~gesamt_man, name="männlich", marker=list(color=toRGB("#775285"))) %>%
layout(barmode="stack", title="Geschlechtsverteilung in den Parteien im Bundestag",
xaxis=list(title="Partei"), yaxis=list(title="Anzahl Abgeordnete")) %>%
layout(legend=list(x=1, y=0.5))
Landtag Geschlechterverteilung Partei
landtag_partei <- Parlamentarier %>%
filter(Kategorie !="Bundestag") %>%
filter(Kategorie!="EU-Parlament") %>%
filter(Partei !="BIW") %>%
filter(Partei!="SSW") %>%
filter(Partei!="BVB/FW") %>%
filter(Partei!="FW")
landtag_partei$Partei[landtag_partei$Partei == "CSU"] <-"CDU/CSU"
landtag_partei$Partei[landtag_partei$Partei=="CDU"] <- "CDU/CSU"
landtag_partei$Partei[landtag_partei$Partei=="FDP/DVP"] <- "FDP"
landtag_man <- landtag_partei %>%
group_by(Partei) %>%
filter(Geschlecht=="männlich") %>%
summarise(gesamt_man=n())
landtag_gesamt <- landtag_partei %>%
group_by(Partei) %>%
filter(Geschlecht=="weiblich") %>%
summarise(gesamt_frau=n()) %>%
left_join(landtag_man) %>%
mutate(row_sum=rowSums(.[2:3])) %>%
arrange(desc(row_sum))
Barchart Landtag
plot_ly(data=landtag_gesamt, x=~reorder(Partei,-row_sum), y=~gesamt_frau, name="weiblich", marker=list(color=toRGB("#FB7F62")),
type="bar", hoverinfo="text", text=~paste("",row_sum),
hovertemplate=paste("Anzahl: %{y:,.0f}",
"<br>Gesamtanzahl: %{text}")) %>%
add_trace(y=~gesamt_man, name="männlich", marker=list(color=toRGB("#775285"))) %>%
layout(barmode="stack", title="Geschlechtsverteilung in den Parteien in den Landtagen",
xaxis=list(title="Partei"), yaxis=list(title="Anzahl Abgeordnete")) %>%
layout(legend=list(x=1, y=0.5))
Map mit Geschlechterverteilung im Bundestag
Alle Landtage herausfiltern
parlamentarier_landtag <- Parlamentarier %>%
filter(Kategorie %in% c("Abgeordnetenhaus von Berlin",
"Bayerischer Landtag",
"Bremische Bürgerschaft",
"Hamburgische Bürgerschaft",
"Hessischer Landtag",
"Landtag Brandenburg",
"Landtag des Saarlandes",
"Landtag Mecklenburg-Vorpommern",
"Landtag Nordrhein-Westfalen",
"Landtag Rheinland-Pfalz",
"Landtag Sachsen-Anhalt",
"Landtag von Baden-Württemberg",
"Niedersächsischer Landtag",
"Sächsischer Landtag",
"Schleswig-Holsteinischer Landtag",
"Thüringer Landtag"))
Vektoren und Datafram erstellen mit den Koordinaten, andenen die Späternen Pie Charts fixiert werden sollen. (Immer genau der Mittelpunkt des Bundeslandes)
Kategorie <- c("Abgeordnetenhaus von Berlin",
"Bayerischer Landtag",
"Bremische Bürgerschaft",
"Hamburgische Bürgerschaft",
"Hessischer Landtag",
"Landtag Brandenburg",
"Landtag des Saarlandes",
"Landtag Mecklenburg-Vorpommern",
"Landtag Nordrhein-Westfalen",
"Landtag Rheinland-Pfalz",
"Landtag Sachsen-Anhalt",
"Landtag von Baden-Württemberg",
"Niedersächsischer Landtag",
"Sächsischer Landtag",
"Schleswig-Holsteinischer Landtag",
"Thüringer Landtag")
lat <- c(52.520008,
48.917431,
53.074982,
53.553815,
50.652052,
52.408418,
49.396423,
53.612651,
51.433237,
50.118346,
51.950265,
48.661604,
52.636704,
51.104541,
54.219367,
51.010989)
lng <- c(13.404954,
11.407980,
8.807080,
9.991575,
9.162438,
12.562492,
7.022961,
12.429595,
7.661594,
7.308953,
11.692274,
9.350134,
9.845077,
13.201738,
9.696117,
10.845346)
bundeslaender_koordinaten <- data.frame(Kategorie, lat, lng)
Tabelle nach Anzahl der männlichen und weiblichen Politiker*innen pro Bundesland filtern.
parlamentarier_man <- parlamentarier_landtag %>%
group_by(Kategorie) %>%
filter(Geschlecht == "männlich") %>%
summarise(männlich = n())
parlamentarier_landtag_gesamt <- parlamentarier_landtag %>%
group_by(Kategorie) %>%
filter(Geschlecht == "weiblich") %>%
summarise(weiblich = n()) %>%
left_join(parlamentarier_man)
Koordinaten der späteren Pie charts zur Haupttabelle joinen
parlamentarier_koordinaten <- parlamentarier_landtag_gesamt %>%
left_join(bundeslaender_koordinaten, by = c("Kategorie" = "Kategorie"))
Map with charts
Farben für die Geschlechter erstellen, sowie die Grenzen der Bundesländer improtieren und mit Namen versehen (popup).
colors <- c("#FB7F62", "#775285")
grenzen <- readRDS("Data/gadm36_DEU_1_sp.rds") %>%
st_as_sf()
popup_bundeslaender <- paste0("<strong>Bundesland: </strong>", grenzen$NAME_1)
Map mit Pie Charts
erstellen, Pie charts mit Hilfe von addMinicharts angefügt.
map <- leaflet() %>%
addProviderTiles(providers$CartoDB.VoyagerLabelsUnder) %>%
setView(lng = 10.451526, lat = 51.165691, zoom = 5.5) %>%
addPolygons(data = grenzen,
fillColor = "grey",
fillOpacity = 0.1,
weight = 3,
color = "grey",
popup = popup_bundeslaender) %>%
addMinicharts(
parlamentarier_koordinaten$lng, parlamentarier_koordinaten$lat,
type = "pie",
chartdata = parlamentarier_koordinaten[, c("weiblich", "männlich")],
colorPalette = colors,
width = 46,
height = 46,
opacity = 0.8,
legendPosition = "bottomright"
)
sf layer has inconsistent datum (+proj=longlat +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +no_defs).
Need '+proj=longlat +datum=WGS84'
map
Barchart
senti_bar <- senti_final_frame %>%
mutate(Partei = fct_reorder(Partei, positive, max)) %>%
pivot_longer(c(positive, negative), values_to = c("Verhältnis"), names_to = c("Äußerung")) %>%
ggplot() +
geom_bar(aes(Partei,
Verhältnis,
fill = Äußerung),
position = "stack",
stat = "identity") +
scale_fill_manual(values = c("#f46666", "#8EC9BB")) +
theme_classic() +
labs(
title = "Äußerungen auf der Politiker*innen auf Twitter zum Thema 'Gender'",
subtitle = "Analyse",
x = "Partei",
y = "Verhältnis",
fill = "Äußerung"
)
final_senti_plot <- ggplotly(senti_bar)
final_senti_plot
LS0tDQp0aXRsZTogIlJfUHJvamVrdF9HZW5kZXIiDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KIyBMb2FkIGxpYnJhcmllcw0KDQpgYGB7cn0NCmxpYnJhcnkodGlkeXRleHQpDQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkocXVhbnRlZGEpDQpsaWJyYXJ5KGx1YnJpZGF0ZSkNCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkocGxvdGx5KQ0KbGlicmFyeShmb3JjYXRzKQ0KbGlicmFyeShyZWFkeGwpDQpsaWJyYXJ5KGxlYWZsZXQpDQpsaWJyYXJ5KGxlYWZsZXQubWluaWNoYXJ0cykNCmxpYnJhcnkoc3ApDQpsaWJyYXJ5KHNmKQ0KbGlicmFyeShyZWFkcikNCmxpYnJhcnkoc3RyaW5ncikNCmxpYnJhcnkocnR3ZWV0KQ0KYGBgDQoNCiMgTG9hZCBEYXRhIA0KDQpgYGB7cn0NClBhcmxhbWVudGFyaWVyIDwtIHJlYWRfY3N2KCJEYXRhL1BhcmxhbWVudGFyaWVyLmNzdiIpDQpgYGANCg0KRVUtUGFybGFtZW50IHJhdXNmaWx0ZXJuDQpgYGB7cn0NClBhcmxhbWVudGFyaWVyIDwtIFBhcmxhbWVudGFyaWVyICU+JSANCiAgZmlsdGVyKEthdGVnb3JpZSE9IkVVLVBhcmxhbWVudCIpDQpgYGANCg0KUmVhZCBUYWJlbGxlbiBtaXQgZmVobGVuZGVuIEdlc2NobGVjaHRlcm4NCmBgYHtyfQ0KYWxsZV9nZXNjaGxlY2h0ZXIgPC0gcmVhZF9leGNlbCgiRGF0YS9QYXJsYW1lbnRhcmllcl9nZXNjaGVjaHRlci54bHN4Iiwgc2hlZXQgPSAiR2VzY2hsZWNodGVyIikNCmBgYA0KDQpKb2luIGZlaGxlbmRlIEdlc2NobGVjaHRlcmFuZ2FiZW4gDQpgYGB7cn0NClBhcmxhbWVudGFyaWVyIDwtIFBhcmxhbWVudGFyaWVyICU+JSANCiAgbGVmdF9qb2luKGFsbGVfZ2VzY2hsZWNodGVyLCBieSA9IGMoIk5hbWUiID0gIk5hbWUiKSkNCmBgYA0KDQpSZW5hbWUgU3BhbHRlbg0KYGBge3J9DQpQYXJsYW1lbnRhcmllciA8LSBQYXJsYW1lbnRhcmllciAlPiUgDQogIHJlbmFtZShHZXNjaGxlY2h0ID0gR2VzY2hsZWNodC55KQ0KYGBgDQoNCkJ1bmRlc3RhZyBHZXNjaGxlY2h0ZXJ2ZXJ0ZWlsdW5nIFBhcnRlaQ0KYGBge3J9DQpidW5kZXN0YWcgPC0gUGFybGFtZW50YXJpZXIgJT4lIA0KICBzZWxlY3QoaWQsIE5hbWUsIEdlc2NobGVjaHQsIFBhcnRlaSwgS2F0ZWdvcmllLCBTTV9Ud2l0dGVyX2lkLCBTTV9Ud2l0dGVyX3VzZXIpICU+JSANCiAgZmlsdGVyKEthdGVnb3JpZT09IkJ1bmRlc3RhZyIpDQoNCmJ1bmRlc3RhZyRQYXJ0ZWlbYnVuZGVzdGFnJFBhcnRlaSA9PSAiQ1NVIl0gPC0iQ0RVL0NTVSINCmJ1bmRlc3RhZyRQYXJ0ZWlbYnVuZGVzdGFnJFBhcnRlaT09IkNEVSJdPC0iQ0RVL0NTVSINCg0KYnVuZGVzdGFnX21hbiA8LSBidW5kZXN0YWcgJT4lIA0KICBncm91cF9ieShQYXJ0ZWkpICU+JSANCiAgZmlsdGVyKEdlc2NobGVjaHQgPT0gIm3DpG5ubGljaCIpICU+JSANCiAgc3VtbWFyaXNlKGdlc2FtdF9tYW49bigpKQ0KDQpidW5kZXN0YWdfZ2VzYW10IDwtIGJ1bmRlc3RhZyAlPiUgDQogIGdyb3VwX2J5KFBhcnRlaSkgJT4lIA0KICBmaWx0ZXIoR2VzY2hsZWNodCA9PSAid2VpYmxpY2giKSAlPiUgDQogIHN1bW1hcmlzZShnZXNhbXRfZnJhdT1uKCkpICU+JSANCiAgbGVmdF9qb2luKGJ1bmRlc3RhZ19tYW4pICU+JSANCiAgbXV0YXRlKHJvd19zdW09cm93U3VtcyguWzI6M10pKSAlPiUgDQogIGFycmFuZ2UoZGVzYyhyb3dfc3VtKSkNCmBgYA0KDQojIEJhcmNoYXJ0IEJ1bmRlc3RhZw0KYGBge3J9DQpwbG90X2x5KGRhdGE9YnVuZGVzdGFnX2dlc2FtdCwgeD1+cmVvcmRlcihQYXJ0ZWksLXJvd19zdW0pLCB5PX5nZXNhbXRfZnJhdSwgbmFtZT0id2VpYmxpY2giLCBtYXJrZXI9bGlzdChjb2xvcj10b1JHQigiI0ZCN0Y2MiIpKSwNCiAgICAgICAgdHlwZT0iYmFyIiwgaG92ZXJpbmZvPSJ0ZXh0IiwgdGV4dD1+cGFzdGUoIiIscm93X3N1bSksIA0KICAgICAgICBob3ZlcnRlbXBsYXRlPXBhc3RlKCJBbnphaGw6ICV7eTosLjBmfSIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICI8YnI+R2VzYW10YW56YWhsOiAle3RleHR9IikpICU+JSANCiAgYWRkX3RyYWNlKHk9fmdlc2FtdF9tYW4sIG5hbWU9Im3DpG5ubGljaCIsIG1hcmtlcj1saXN0KGNvbG9yPXRvUkdCKCIjNzc1Mjg1IikpKSAlPiUgDQogIGxheW91dChiYXJtb2RlPSJzdGFjayIsIHRpdGxlPSJHZXNjaGxlY2h0ZXJ2ZXJ0ZWlsdW5nIGluIGRlbiBQYXJ0ZWllbiBpbSBCdW5kZXN0YWciLCANCiAgICAgICAgIHhheGlzPWxpc3QodGl0bGU9IlBhcnRlaSIpLCB5YXhpcz1saXN0KHRpdGxlPSJBbnphaGwgQWJnZW9yZG5ldGUiKSkgJT4lDQogIGxheW91dChsZWdlbmQ9bGlzdCh4PTEsIHk9MC41KSkNCmBgYA0KDQpMYW5kdGFnIEdlc2NobGVjaHRlcnZlcnRlaWx1bmcgUGFydGVpDQoNCmBgYHtyfQ0KbGFuZHRhZ19wYXJ0ZWkgPC0gUGFybGFtZW50YXJpZXIgJT4lIA0KICBmaWx0ZXIoS2F0ZWdvcmllICE9IkJ1bmRlc3RhZyIpICU+JSANCiAgZmlsdGVyKEthdGVnb3JpZSE9IkVVLVBhcmxhbWVudCIpICU+JSANCiAgZmlsdGVyKFBhcnRlaSAhPSJCSVciKSAlPiUgDQogIGZpbHRlcihQYXJ0ZWkhPSJTU1ciKSAlPiUgDQogIGZpbHRlcihQYXJ0ZWkhPSJCVkIvRlciKSAlPiUgDQogIGZpbHRlcihQYXJ0ZWkhPSJGVyIpDQpgYGANCg0KYGBge3J9DQpsYW5kdGFnX3BhcnRlaSRQYXJ0ZWlbbGFuZHRhZ19wYXJ0ZWkkUGFydGVpID09ICJDU1UiXSA8LSJDRFUvQ1NVIg0KbGFuZHRhZ19wYXJ0ZWkkUGFydGVpW2xhbmR0YWdfcGFydGVpJFBhcnRlaT09IkNEVSJdIDwtICJDRFUvQ1NVIg0KbGFuZHRhZ19wYXJ0ZWkkUGFydGVpW2xhbmR0YWdfcGFydGVpJFBhcnRlaT09IkZEUC9EVlAiXSA8LSAiRkRQIiANCmBgYA0KDQpgYGB7cn0NCmxhbmR0YWdfbWFuIDwtIGxhbmR0YWdfcGFydGVpICU+JSANCiAgZ3JvdXBfYnkoUGFydGVpKSAlPiUgDQogIGZpbHRlcihHZXNjaGxlY2h0PT0ibcOkbm5saWNoIikgJT4lIA0KICBzdW1tYXJpc2UoZ2VzYW10X21hbj1uKCkpDQoNCmxhbmR0YWdfZ2VzYW10IDwtIGxhbmR0YWdfcGFydGVpICU+JSANCiAgZ3JvdXBfYnkoUGFydGVpKSAlPiUgDQogIGZpbHRlcihHZXNjaGxlY2h0PT0id2VpYmxpY2giKSAlPiUgDQogIHN1bW1hcmlzZShnZXNhbXRfZnJhdT1uKCkpICU+JSANCiAgbGVmdF9qb2luKGxhbmR0YWdfbWFuKSAlPiUgDQogICBtdXRhdGUocm93X3N1bT1yb3dTdW1zKC5bMjozXSkpICU+JSANCiAgYXJyYW5nZShkZXNjKHJvd19zdW0pKQ0KYGBgDQoNCiMgQmFyY2hhcnQgTGFuZHRhZw0KYGBge3J9DQpwbG90X2x5KGRhdGE9bGFuZHRhZ19nZXNhbXQsIHg9fnJlb3JkZXIoUGFydGVpLC1yb3dfc3VtKSwgeT1+Z2VzYW10X2ZyYXUsIG5hbWU9IndlaWJsaWNoIiwgbWFya2VyPWxpc3QoY29sb3I9dG9SR0IoIiNGQjdGNjIiKSksIA0KICAgICAgICB0eXBlPSJiYXIiLCBob3ZlcmluZm89InRleHQiLCB0ZXh0PX5wYXN0ZSgiIixyb3dfc3VtKSwgDQogICAgICAgIGhvdmVydGVtcGxhdGU9cGFzdGUoIkFuemFobDogJXt5OiwuMGZ9IiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIjxicj5HZXNhbXRhbnphaGw6ICV7dGV4dH0iKSkgJT4lIA0KICBhZGRfdHJhY2UoeT1+Z2VzYW10X21hbiwgbmFtZT0ibcOkbm5saWNoIiwgbWFya2VyPWxpc3QoY29sb3I9dG9SR0IoIiM3NzUyODUiKSkpICU+JSANCiAgbGF5b3V0KGJhcm1vZGU9InN0YWNrIiwgdGl0bGU9Ikdlc2NobGVjaHRlcnZlcnRlaWx1bmcgaW4gZGVuIFBhcnRlaWVuIGluIGRlbiBMYW5kdGFnZW4iLCANCiAgICAgICAgIHhheGlzPWxpc3QodGl0bGU9IlBhcnRlaSIpLCB5YXhpcz1saXN0KHRpdGxlPSJBbnphaGwgQWJnZW9yZG5ldGUiKSkgJT4lDQogIGxheW91dChsZWdlbmQ9bGlzdCh4PTEsIHk9MC41KSkNCmBgYA0KDQojIE1hcCBtaXQgR2VzY2hsZWNodGVydmVydGVpbHVuZyBpbSBCdW5kZXN0YWcNCkFsbGUgTGFuZHRhZ2UgaGVyYXVzZmlsdGVybg0KYGBge3J9DQpwYXJsYW1lbnRhcmllcl9sYW5kdGFnIDwtIFBhcmxhbWVudGFyaWVyICU+JSANCiAgZmlsdGVyKEthdGVnb3JpZSAlaW4lIGMoIkFiZ2VvcmRuZXRlbmhhdXMgdm9uIEJlcmxpbiIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAiQmF5ZXJpc2NoZXIgTGFuZHRhZyIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAiQnJlbWlzY2hlIELDvHJnZXJzY2hhZnQiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgIkhhbWJ1cmdpc2NoZSBCw7xyZ2Vyc2NoYWZ0IiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICJIZXNzaXNjaGVyIExhbmR0YWciLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgIkxhbmR0YWcgQnJhbmRlbmJ1cmciLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgIkxhbmR0YWcgZGVzIFNhYXJsYW5kZXMiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgIkxhbmR0YWcgTWVja2xlbmJ1cmctVm9ycG9tbWVybiIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAiTGFuZHRhZyBOb3JkcmhlaW4tV2VzdGZhbGVuIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICJMYW5kdGFnIFJoZWlubGFuZC1QZmFseiIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAiTGFuZHRhZyBTYWNoc2VuLUFuaGFsdCIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAiTGFuZHRhZyB2b24gQmFkZW4tV8O8cnR0ZW1iZXJnIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICJOaWVkZXJzw6RjaHNpc2NoZXIgTGFuZHRhZyIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAiU8OkY2hzaXNjaGVyIExhbmR0YWciLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgIlNjaGxlc3dpZy1Ib2xzdGVpbmlzY2hlciBMYW5kdGFnIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICJUaMO8cmluZ2VyIExhbmR0YWciKSkNCmBgYA0KDQpWZWt0b3JlbiB1bmQgRGF0YWZyYW0gZXJzdGVsbGVuIG1pdCBkZW4gS29vcmRpbmF0ZW4sIGFuZGVuZW4gZGllIFNww6R0ZXJuZW4gUGllIENoYXJ0cyBmaXhpZXJ0IHdlcmRlbiBzb2xsZW4uIChJbW1lciBnZW5hdSBkZXIgTWl0dGVscHVua3QgZGVzIEJ1bmRlc2xhbmRlcykNCg0KYGBge3J9DQpLYXRlZ29yaWUgPC0gYygiQWJnZW9yZG5ldGVuaGF1cyB2b24gQmVybGluIiwgDQogICAgICAgICAgICAgICAiQmF5ZXJpc2NoZXIgTGFuZHRhZyIsIA0KICAgICAgICAgICAgICAgIkJyZW1pc2NoZSBCw7xyZ2Vyc2NoYWZ0IiwNCiAgICAgICAgICAgICAgICJIYW1idXJnaXNjaGUgQsO8cmdlcnNjaGFmdCIsIA0KICAgICAgICAgICAgICAgIkhlc3Npc2NoZXIgTGFuZHRhZyIsDQogICAgICAgICAgICAgICAiTGFuZHRhZyBCcmFuZGVuYnVyZyIsIA0KICAgICAgICAgICAgICAgIkxhbmR0YWcgZGVzIFNhYXJsYW5kZXMiLA0KICAgICAgICAgICAgICAgIkxhbmR0YWcgTWVja2xlbmJ1cmctVm9ycG9tbWVybiIsDQogICAgICAgICAgICAgICAiTGFuZHRhZyBOb3JkcmhlaW4tV2VzdGZhbGVuIiwNCiAgICAgICAgICAgICAgICJMYW5kdGFnIFJoZWlubGFuZC1QZmFseiIsDQogICAgICAgICAgICAgICAiTGFuZHRhZyBTYWNoc2VuLUFuaGFsdCIsIA0KICAgICAgICAgICAgICAgIkxhbmR0YWcgdm9uIEJhZGVuLVfDvHJ0dGVtYmVyZyIsIA0KICAgICAgICAgICAgICAgIk5pZWRlcnPDpGNoc2lzY2hlciBMYW5kdGFnIiwgDQogICAgICAgICAgICAgICAiU8OkY2hzaXNjaGVyIExhbmR0YWciLCANCiAgICAgICAgICAgICAgICJTY2hsZXN3aWctSG9sc3RlaW5pc2NoZXIgTGFuZHRhZyIsIA0KICAgICAgICAgICAgICAgIlRow7xyaW5nZXIgTGFuZHRhZyIpDQoNCmxhdCA8LSBjKDUyLjUyMDAwOCwNCiAgICAgICAgIDQ4LjkxNzQzMSwNCiAgICAgICAgIDUzLjA3NDk4MiwNCiAgICAgICAgIDUzLjU1MzgxNSwNCiAgICAgICAgIDUwLjY1MjA1MiwNCiAgICAgICAgIDUyLjQwODQxOCwNCiAgICAgICAgIDQ5LjM5NjQyMywNCiAgICAgICAgIDUzLjYxMjY1MSwNCiAgICAgICAgIDUxLjQzMzIzNywNCiAgICAgICAgIDUwLjExODM0NiwNCiAgICAgICAgIDUxLjk1MDI2NSwNCiAgICAgICAgIDQ4LjY2MTYwNCwNCiAgICAgICAgIDUyLjYzNjcwNCwNCiAgICAgICAgIDUxLjEwNDU0MSwNCiAgICAgICAgIDU0LjIxOTM2NywNCiAgICAgICAgIDUxLjAxMDk4OSkNCg0KbG5nIDwtIGMoMTMuNDA0OTU0LA0KICAgICAgICAgMTEuNDA3OTgwLA0KICAgICAgICAgOC44MDcwODAsDQogICAgICAgICA5Ljk5MTU3NSwNCiAgICAgICAgIDkuMTYyNDM4LA0KICAgICAgICAgMTIuNTYyNDkyLA0KICAgICAgICAgNy4wMjI5NjEsDQogICAgICAgICAxMi40Mjk1OTUsDQogICAgICAgICA3LjY2MTU5NCwNCiAgICAgICAgIDcuMzA4OTUzLA0KICAgICAgICAgMTEuNjkyMjc0LA0KICAgICAgICAgOS4zNTAxMzQsDQogICAgICAgICA5Ljg0NTA3NywNCiAgICAgICAgIDEzLjIwMTczOCwNCiAgICAgICAgIDkuNjk2MTE3LA0KICAgICAgICAgMTAuODQ1MzQ2KQ0KDQpidW5kZXNsYWVuZGVyX2tvb3JkaW5hdGVuIDwtIGRhdGEuZnJhbWUoS2F0ZWdvcmllLCBsYXQsIGxuZykNCmBgYA0KDQpUYWJlbGxlIG5hY2ggQW56YWhsIGRlciBtw6RubmxpY2hlbiB1bmQgd2VpYmxpY2hlbiBQb2xpdGlrZXIqaW5uZW4gcHJvIEJ1bmRlc2xhbmQgZmlsdGVybi4NCg0KYGBge3J9DQpwYXJsYW1lbnRhcmllcl9tYW4gPC0gcGFybGFtZW50YXJpZXJfbGFuZHRhZyAlPiUgDQogIGdyb3VwX2J5KEthdGVnb3JpZSkgJT4lIA0KICBmaWx0ZXIoR2VzY2hsZWNodCA9PSAibcOkbm5saWNoIikgJT4lIA0KICBzdW1tYXJpc2UobcOkbm5saWNoID0gbigpKQ0KDQpwYXJsYW1lbnRhcmllcl9sYW5kdGFnX2dlc2FtdCA8LSBwYXJsYW1lbnRhcmllcl9sYW5kdGFnICU+JSANCiAgZ3JvdXBfYnkoS2F0ZWdvcmllKSAlPiUgDQogIGZpbHRlcihHZXNjaGxlY2h0ID09ICJ3ZWlibGljaCIpICU+JSANCiAgc3VtbWFyaXNlKHdlaWJsaWNoID0gbigpKSAlPiUgDQogIGxlZnRfam9pbihwYXJsYW1lbnRhcmllcl9tYW4pDQpgYGANCg0KS29vcmRpbmF0ZW4gZGVyIHNww6R0ZXJlbiBQaWUgY2hhcnRzIHp1ciBIYXVwdHRhYmVsbGUgam9pbmVuDQoNCmBgYHtyfQ0KcGFybGFtZW50YXJpZXJfa29vcmRpbmF0ZW4gPC0gcGFybGFtZW50YXJpZXJfbGFuZHRhZ19nZXNhbXQgJT4lIA0KICBsZWZ0X2pvaW4oYnVuZGVzbGFlbmRlcl9rb29yZGluYXRlbiwgYnkgPSBjKCJLYXRlZ29yaWUiID0gIkthdGVnb3JpZSIpKQ0KYGBgDQoNCiMgTWFwIHdpdGggY2hhcnRzDQpGYXJiZW4gZsO8ciBkaWUgR2VzY2hsZWNodGVyIGVyc3RlbGxlbiwgc293aWUgZGllIEdyZW56ZW4gZGVyIEJ1bmRlc2zDpG5kZXIgaW1wcm90aWVyZW4gdW5kIG1pdCBOYW1lbiB2ZXJzZWhlbiAocG9wdXApLg0KYGBge3J9DQpjb2xvcnMgPC0gYygiI0ZCN0Y2MiIsICIjNzc1Mjg1IikNCg0KZ3JlbnplbiA8LSByZWFkUkRTKCJEYXRhL2dhZG0zNl9ERVVfMV9zcC5yZHMiKSAlPiUgDQogIHN0X2FzX3NmKCkNCg0KcG9wdXBfYnVuZGVzbGFlbmRlciA8LSBwYXN0ZTAoIjxzdHJvbmc+QnVuZGVzbGFuZDogPC9zdHJvbmc+IiwgZ3JlbnplbiROQU1FXzEpDQpgYGANCg0KIyBNYXAgbWl0IFBpZSBDaGFydHMgDQplcnN0ZWxsZW4sIFBpZSBjaGFydHMgbWl0IEhpbGZlIHZvbiBhZGRNaW5pY2hhcnRzIGFuZ2Vmw7xndC4gDQoNCmBgYHtyfQ0KbWFwIDwtIGxlYWZsZXQoKSAlPiUgDQogIGFkZFByb3ZpZGVyVGlsZXMocHJvdmlkZXJzJENhcnRvREIuVm95YWdlckxhYmVsc1VuZGVyKSAlPiUgDQogIHNldFZpZXcobG5nID0gMTAuNDUxNTI2LCBsYXQgPSA1MS4xNjU2OTEsIHpvb20gPSA1LjUpICU+JSANCiAgYWRkUG9seWdvbnMoZGF0YSA9IGdyZW56ZW4sDQogICAgICAgICAgICAgIGZpbGxDb2xvciA9ICJncmV5IiwNCiAgICAgICAgICAgICAgZmlsbE9wYWNpdHkgPSAwLjEsDQogICAgICAgICAgICAgIHdlaWdodCA9IDMsDQogICAgICAgICAgICAgIGNvbG9yID0gImdyZXkiLA0KICAgICAgICAgICAgICBwb3B1cCA9IHBvcHVwX2J1bmRlc2xhZW5kZXIpICU+JSANCiAgYWRkTWluaWNoYXJ0cygNCiAgICBwYXJsYW1lbnRhcmllcl9rb29yZGluYXRlbiRsbmcsIHBhcmxhbWVudGFyaWVyX2tvb3JkaW5hdGVuJGxhdCwNCiAgICB0eXBlID0gInBpZSIsDQogICAgY2hhcnRkYXRhID0gcGFybGFtZW50YXJpZXJfa29vcmRpbmF0ZW5bLCBjKCJ3ZWlibGljaCIsICJtw6RubmxpY2giKV0sDQogICAgY29sb3JQYWxldHRlID0gY29sb3JzLA0KICAgIHdpZHRoID0gNDYsDQogICAgaGVpZ2h0ID0gNDYsDQogICAgb3BhY2l0eSA9IDAuOCwNCiAgICBsZWdlbmRQb3NpdGlvbiA9ICJib3R0b21yaWdodCINCiAgKQ0KbWFwDQpgYGANCg0KIyBUd2VldHMgZGVyIFBvbGl0aWtlcippbm5lbiBzY3JhcGVuDQoNCk5pY2h0IGFscyBhdXNmw7xocmJhcmVuIENvZGUsIGRhbWl0IGRpZSBEYXRlbiBuaWNodCBub2NobWFscyBnZXpvZ2VuIHdlcmRlbi4uLg0KDQpUd2l0dGVyX2FjY291bnRzIDwtIFBhcmxhbWVudGFyaWVyICU+JQ0KICBmaWx0ZXIoS2F0ZWdvcmllIT0iRVUtUGFybGFtZW50IikgJT4lDQogIGZpbHRlcihQYXJ0ZWkhPSJCSVciKSAlPiUgDQogIGZpbHRlcihQYXJ0ZWkhPSJTU1ciKSAlPiUgDQogIGZpbHRlcihQYXJ0ZWkhPSJCVkIvRlciKSAlPiUgDQogIGZpbHRlcihQYXJ0ZWkhPSJGVyIpICU+JSANCiAgZmlsdGVyKFBhcnRlaSE9ImZyYWt0aW9uc2xvcyIpICU+JSANCiAgZmlsdGVyKFNNX1R3aXR0ZXJfdXNlciAhPSAiIikNCg0KdG9rZW4gPC0gZ2V0X3Rva2VuKCkNCnRva2VuDQoNCmFsbGVfdHdlZXRzIDwtIGxpc3QoKQ0KdXNlcklkTGlzdCA9IGxpc3QoVHdpdHRlcl9hY2NvdW50cyRTTV9Ud2l0dGVyX3VzZXIpDQpybCA8LSByYXRlX2xpbWl0KHRva2VuLCAic3RhdHVzZXMvdXNlcl90aW1lbGluZSIpDQpmb3IodXNlciBpbiB1c2VySWRMaXN0W1sxXV0pew0KICBhbGxlX3R3ZWV0c1tbdXNlcl1dIDwtIGdldF90aW1lbGluZSh1c2VyLCBuID0gMiwgY2hlY2sgPSBGKQ0KICBwcmludCgicmF0ZSBsaW1pdCByZW1haW5pbmc6Iiwgc3RyKHJsJHJlbWFpbmluZykpDQogIHByaW50KCJhdCB1c2VyOiIsIHN0cih1c2VyKSkNCiAgcmwgPC0gcmwgJT4lDQogICAgbXV0YXRlKHJlbWFpbmluZyA9IHJlbWFpbmluZyAtIDEpDQogICMgaWYgcmF0ZSBsaW1pdCBleGhhdXN0ZWQsIHRoZW4gd2FpdCB0byByYXRlIGxpbWl0IHJlc2V0DQogIGlmIChybCRyZW1haW5pbmcgPT0gNUwpIHsNCiAgICBybCA8LSByYXRlX2xpbWl0KHRva2VuLCAic3RhdHVzZXMvdXNlcl90aW1lbGluZSIpDQogICAgcHJpbnQoInJhdGUgbGltaXQgZXhjZWVkZWQsIHdhaXRpbmcgZm9yIDkwMHMgYXQgdXNlciIsIHN0cih1c2VyKSkNCiAgICBTeXMuc2xlZXAoYXMubnVtZXJpYyhybCRyZXNldCwgInNlY3MiKSkNCiAgfQ0KfQ0KDQojIE5hY2ggcmVsZXZhbnRlbiBIYXNodGFncyBmaWx0ZXJuIA0KDQoiYWxsZV90d2VldHMiIGlzdCBkaWUgRGF0ZWkgbWl0IGFsbGVuIGdlem9nZW5lbiBUd2VldHMuDQpgYGB7cn0NCmFsbGVfdHdlZXRzIDwtIHJlYWRfcmRzKCJEYXRhL2FsbGVfdHdlZXRzLnJkcyIpDQoNCnN1Y2hiZWdyaWZmZSA8LSByZWFkX2V4Y2VsKCJEYXRhL1R3aXR0ZXItSGFzaHRhZ3MueGxzeCIsIHNoZWV0ID0iVGFiZWxsZTIiKQ0KDQpzdWNoYmVncmlmZmVfdmVjdG9yIDwtIHN1Y2hiZWdyaWZmZSRIYXNodGFncw0KDQphbGxlX3R3ZWV0cyA8LSBiaW5kX3Jvd3MoYWxsZV90d2VldHMpDQoNCmFsbGVfdHdlZXRzIDwtIGFsbGVfdHdlZXRzICU+JSANCiAgbXV0YXRlKHRleHQgPSB0b2xvd2VyKHRleHQpKQ0KDQpmaWx0ZXJ0X3R3ZWV0cyA8LSBhbGxlX3R3ZWV0cyAlPiUgDQogIGZpbHRlcihzdHJfZGV0ZWN0KHRleHQsIHBhc3RlIChzdWNoYmVncmlmZmVfdmVjdG9yLCBjb2xsYXBzZSA9ICJ8IikpKQ0KDQp3cml0ZV9yZHMoZmlsdGVydF90d2VldHMsICJmaW5hbF90d2VldHMucmRzIikNCmBgYA0KDQojU2VudGltZW50YW5hbHlzZQ0KDQpgYGB7cn0NClBhcmxhbWVudGFyaWVyX3NlbnRpIDwtIFBhcmxhbWVudGFyaWVyICU+JSANCiAgZmlsdGVyKFBhcnRlaSE9IkJJVyIpICU+JSANCiAgZmlsdGVyKFBhcnRlaSE9IlNTVyIpICU+JSANCiAgZmlsdGVyKFBhcnRlaSE9IkJWQi9GVyIpICU+JSANCiAgZmlsdGVyKFBhcnRlaSE9IkZXIikgJT4lIA0KICBmaWx0ZXIoUGFydGVpIT0iZnJha3Rpb25zbG9zIikgJT4lIA0KICBmaWx0ZXIoU01fVHdpdHRlcl91c2VyICE9ICIiKSAlPiUgDQogIHNlbGVjdChOYW1lLCBQYXJ0ZWksIFNNX1R3aXR0ZXJfdXNlciwgR2VzY2hsZWNodCkgJT4lIA0KICBtdXRhdGUoU01fVHdpdHRlcl91c2VyPXRvbG93ZXIoU01fVHdpdHRlcl91c2VyKSkNCmBgYA0KDQpXZXJ0IFVtd2FuZGx1bmcgdW0gQ0RVL0NTVSAmIEZEUC9EVlAgenVzYW1tZW56dWZhc3Nlbg0KYGBge3J9DQpQYXJsYW1lbnRhcmllcl9zZW50aSRQYXJ0ZWlbUGFybGFtZW50YXJpZXJfc2VudGkkUGFydGVpID09ICJDU1UiXSA8LSAiQ0RVL0NTVSINClBhcmxhbWVudGFyaWVyX3NlbnRpJFBhcnRlaVtQYXJsYW1lbnRhcmllcl9zZW50aSRQYXJ0ZWkgPT0gIkNEVSJdIDwtICJDRFUvQ1NVIg0KUGFybGFtZW50YXJpZXJfc2VudGkkUGFydGVpW1BhcmxhbWVudGFyaWVyX3NlbnRpJFBhcnRlaSA9PSAiRkRQL0RWUCJdIDwtICJGRFAiIA0KYGBgDQoNCmBgYHtyfQ0KbG9hZCgiRGF0YS9zZW50aVdTLlJEYXRhIikNCnNlbnRpd3MgPC0gZGljdGlvbmFyeShsaXN0KHBvc2l0aXZlPXBvc2l0aXZlLCBuZWdhdGl2ZT1uZWdhdGl2ZSkpDQpgYGANCg0KYGBge3J9DQp0d2VldF9jb3JwdXMgPC0gY29ycHVzKGFsbGVfdHdlZXRzLCB0ZXh0X2ZpZWxkID0gInRleHQiKQ0KYGBgDQoNCnRva2VuaXNpZXJlbg0KDQpgYGB7cn0NCnRva2VuIDwtIHRva2Vucyh0d2VldF9jb3JwdXMpDQpkZm0gPC0gZGZtKHRva2VuKQ0KDQpzZW50aSA8LSBkZm1fbG9va3VwKGRmbSwgc2VudGl3cykgIA0Kc2VudGkgPC0gZGZtX2dyb3VwKHNlbnRpLCBncm91cHMgPSBzY3JlZW5fbmFtZSkNCmBgYA0KDQpgYGB7cn0NCnNlbnRpX2ZyYW1lIDwtIHNlbnRpICU+JSANCiAgY29udmVydCh0bz0iZGF0YS5mcmFtZSIpICU+JSANCiAgYXNfdGliYmxlKCkgJT4lIA0KICBtdXRhdGUoZG9jX2lkPXRvbG93ZXIoZG9jX2lkKSkNCg0Kc2VudGlfZmluYWxfZnJhbWUgPC0gc2VudGlfZnJhbWUgJT4lIA0KICBmdWxsX2pvaW4oUGFybGFtZW50YXJpZXJfc2VudGksIGJ5PWMoImRvY19pZCI9IlNNX1R3aXR0ZXJfdXNlciIpKSAlPiUgDQogIGdyb3VwX2J5KFBhcnRlaSkgJT4lIA0KICBzdW1tYXJpc2UoYWNyb3NzKGMobmVnYXRpdmUsIHBvc2l0aXZlKSwgfnJvdW5kKHN1bSguLCBuYS5ybSA9IFRSVUUpL3N1bShuZWdhdGl2ZSArIHBvc2l0aXZlLCBuYS5ybSA9IFRSVUUgKSwgZGlnaXRzID0gMikpKQ0KYGBgDQoNCiMgQmFyY2hhcnQNCmBgYHtyfQ0Kc2VudGlfYmFyIDwtIHNlbnRpX2ZpbmFsX2ZyYW1lICU+JSANCiAgbXV0YXRlKFBhcnRlaSA9IGZjdF9yZW9yZGVyKFBhcnRlaSwgcG9zaXRpdmUsIG1heCkpICU+JSANCiAgcGl2b3RfbG9uZ2VyKGMocG9zaXRpdmUsIG5lZ2F0aXZlKSwgdmFsdWVzX3RvID0gYygiVmVyaMOkbHRuaXMiKSwgbmFtZXNfdG8gPSBjKCLDhHXDn2VydW5nIikpICU+JSANCiAgZ2dwbG90KCkgKyANCiAgZ2VvbV9iYXIoYWVzKFBhcnRlaSwNCiAgICAgICAgICAgICAgIFZlcmjDpGx0bmlzLCAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgZmlsbCA9IMOEdcOfZXJ1bmcpLA0KICAgICAgICAgICBwb3NpdGlvbiA9ICJzdGFjayIsDQogICAgICAgICAgIHN0YXQgPSAiaWRlbnRpdHkiKSArDQogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoIiNmNDY2NjYiLCAiIzhFQzlCQiIpKSArIA0KICB0aGVtZV9jbGFzc2ljKCkgKyANCiAgbGFicygNCiAgICB0aXRsZSA9ICLDhHXDn2VydW5nZW4gYXVmIGRlciBQb2xpdGlrZXIqaW5uZW4gYXVmIFR3aXR0ZXIgenVtIFRoZW1hICdHZW5kZXInIiwNCiAgICBzdWJ0aXRsZSA9ICJBbmFseXNlIiwNCiAgICB4ID0gIlBhcnRlaSIsDQogICAgeSA9ICJWZXJow6RsdG5pcyIsDQogICAgZmlsbCA9ICLDhHXDn2VydW5nIg0KICApDQoNCmZpbmFsX3NlbnRpX3Bsb3QgPC0gZ2dwbG90bHkoc2VudGlfYmFyKQ0KZmluYWxfc2VudGlfcGxvdA0KYGBgDQoNCg0K